package com.sina.shop.dao.business;

import com.sina.shop.dao.ShopDataSourceDao;
import com.sina.shop.domain.Status;
import com.sina.shop.domain.business.Business;
import com.sina.shop.domain.business.Business_;
import com.sina.shop.domain.goods.Goods;
import com.sina.shop.domain.goods.Goods_;
import org.hibernate.query.Query;
import org.springframework.stereotype.Repository;

import javax.persistence.NoResultException;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * 段浩杰   2018-02-05-14:09
 */
@Repository("businessDao")
public class BusinessDaoImpl extends ShopDataSourceDao implements BusinessDao {

    @Override
    public Integer deleteBusinessTab(Long id) {
        String hql = "update Business b set b.status = :status where b.id = :id";
        return template.executeWithNativeSession(session -> {
            Query query = session.createQuery(hql);
            query.setParameter("id", id);
            query.setParameter("status", Status.NOT_USE);
            return query.executeUpdate();
        });
    }

    @Override
    public List<Business> getBusinessByAdminId(Long adminId) {
        String hql = "from Business b where b.admin.id= :adminId";
        return list(hql, new String[]{"adminId"}, new Object[]{adminId}, -1, -1);
    }

    @Override
    public List<Business> getBusinessList(Business business) {
        return template.executeWithNativeSession(session -> {

            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaQuery<Business> criteriaQuery = builder.createQuery(Business.class);
            Root<Business> root = criteriaQuery.from(Business.class);
            Predicate predicate = businessPredicate(business, builder, root);
            criteriaQuery.where(predicate);
            criteriaQuery.orderBy(
                    builder.desc(root.get(Business_.credit)),
                    builder.desc(root.get(Business_.isGroom)),
                    builder.asc(root.get(Business_.createTime)),
                    builder.desc(root.get(Business_.id))
            );

            Query<Business> query = session.createQuery(criteriaQuery);
            int first = (business.getPage() - 1) * business.getRows();
            query.setFirstResult(first);
            query.setMaxResults(business.getRows());

            return query.getResultList();
        });
    }

    @Override
    public Long getBusinessCount(Business business) {
        return template.executeWithNativeSession(session -> {

            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaQuery<Long> criteriaQuery = builder.createQuery(Long.class);
            Root<Business> root = criteriaQuery.from(Business.class);
            //根据id查找结果数
            criteriaQuery.select(
                    builder.count(root.get(Business_.id))
            );
            //组装查询条件
            criteriaQuery.where(
                    businessPredicate(business, builder, root)
            );
            //创建插叙语句
            Query<Long> query = session.createQuery(criteriaQuery);
            long count;
            try {
                //得到结果条数
                count = query.getSingleResult();
            } catch (NoResultException e) {
                count = 0;
            }
            return count;
        });
    }


    protected Predicate businessPredicate(Business business, CriteriaBuilder builder
            , Root<Business> root) {
        List<Predicate> list = new ArrayList<>(4);
        if (business.getLastId() != null) {
            list.add(
                    builder.lt(root.get(Business_.id), business.getLastId())
            );
        }
        //名字
        if (business.getName() != null) {
            list.add(
                    builder.like(root.get(Business_.name), "%" + business.getName() + "%")
            );
        }

        //
        if (business.getIsGroom() != null) {
            list.add(
                    builder.equal(root.get(Business_.isGroom), business.getIsGroom())
            );
        }
        return builder.and(
                list.toArray(new Predicate[list.size()])
        );
    }
}
